/*
 * Copyright (C) 2009 Jiannan Lu
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.restsql.data;

/**
 *
 * @author L
 */
public class Protocol {

    /** Indicates that the port number is undefined. */
    public static final int UNKNOWN_PORT = -1;


    /** All protocols wildcard. */
    public static final Protocol ALL = new Protocol("all", "ALL",
            "Wildcard for all protocols", UNKNOWN_PORT);

    /** FTP protocol. */
    public static final Protocol FTP = new Protocol("ftp", "FTP",
            "File Transfer Protocol", 21);

    /** HTTP protocol. */
    public static final Protocol HTTP = new Protocol("http", "HTTP",
            "HyperText Transport Protocol", 80);

    /** HTTPS protocol (via SSL socket). */
    public static final Protocol HTTPS = new Protocol("https", "HTTPS",
            "HyperText Transport Protocol (Secure)", 443, true);

   
    /**
     * Creates the protocol associated to a URI scheme name. If an existing
     * constant exists then it is returned, otherwise a new instance is created.
     *
     * @param name
     *            The scheme name.
     * @return The associated protocol.
     */
    public static Protocol valueOf(final String name) {
        Protocol result = null;

        if ((name != null) && !name.equals("")) {
            if (name.equalsIgnoreCase(FTP.getSchemeName())) {
                result = FTP;
            } else if (name.equalsIgnoreCase(HTTP.getSchemeName())) {
                result = HTTP;
            } else if (name.equalsIgnoreCase(HTTPS.getSchemeName())) {
                result = HTTPS;
            }
            else {
                result = new Protocol(name);
            }
        }

        return result;
    }

    /** The confidentiality. */
    private volatile boolean confidential;

    /** The default port if known or -1. */
    private volatile int defaultPort;

    /** The scheme name. */
    private volatile String schemeName;

    /**
     * Constructor.
     *
     * @param schemeName
     *            The scheme name.
     */
    public Protocol(final String schemeName) {
        this(schemeName, schemeName.toUpperCase(), schemeName.toUpperCase()
                + " Protocol", UNKNOWN_PORT);
    }

    /**
     * Constructor.
     *
     * @param schemeName
     *            The scheme name.
     * @param name
     *            The unique name.
     * @param description
     *            The description.
     * @param defaultPort
     *            The default port.
     */
    public Protocol(final String schemeName, final String name,
            final String description, int defaultPort) {
        this(schemeName, name, description, defaultPort, false);
    }

    /**
     * Constructor.
     *
     * @param schemeName
     *            The scheme name.
     * @param name
     *            The unique name.
     * @param description
     *            The description.
     * @param defaultPort
     *            The default port.
     * @param confidential
     *            The confidentiality.
     */
    public Protocol(final String schemeName, final String name,
            final String description, int defaultPort,
            final boolean confidential) {
        this.schemeName = schemeName;
        this.defaultPort = defaultPort;
        this.confidential = confidential;
    }


    /**
     * Returns the default port number.
     *
     * @return The default port number.
     */
    public int getDefaultPort() {
        return this.defaultPort;
    }

    /**
     * Returns the URI scheme name.
     *
     * @return The URI scheme name.
     */
    public String getSchemeName() {
        return this.schemeName;
    }

    /**
     * Indicates if the protocol guarantees the confidentially of the messages
     * exchanged, for example via a SSL-secured connection.
     *
     * @return True if the protocol is confidential.
     */
    public boolean isConfidential() {
        return this.confidential;
    }


}
